package top.infopub.mgr.bpa.web;


import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import top.infopub.mgr.bpa.domain.BizDataDomain;
import top.infopub.mgr.bpa.service.BizDataService;
import top.infopub.mgr.bpa.service.ProContractService;
import top.infopub.mgr.bpa.vo.BizDataExcelVo;
import top.infopub.mgr.bpa.vo.BizDataVo;
import top.infopub.mgr.common.page.ParamPage;
import top.infopub.mgr.common.vo.ErrorCodeEnum;
import top.infopub.mgr.common.vo.RspVo;
import top.infopub.mgr.flow.web.GenericFlowController;
import top.infopub.mgr.hr.service.StaffInfoService;
import top.infopub.mgr.util.DateUtils;
import top.infopub.mgr.util.ExcelParseUtil;
import top.infopub.mgr.util.LogUtil;
import top.infopub.mgr.util.LogUtil.AcctionType;
import top.infopub.mgr.util.LogUtil.LogModelType;
import top.infopub.mgr.util.ObjectCheckUtil;
import top.infopub.model.bpa.BizDataDetail;
import top.infopub.model.bpa.ProContract;
import top.infopub.model.hr.StaffInfo;
import top.infopub.security.util.SessionUserUtils;
import top.infopub.security.vo.AuthorizationVO;
import top.infopub.tdp.sys.service.CodeGeneratorConfigService;
import top.infopub.util.IdFactory;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.github.pagehelper.Page;


/**
 * 商务数据完成情况
 * @author Awoke
 * @version 2020年3月18日
 * @see BizDataController
 * @since
 */
@Controller
@RequestMapping("/bizData")
public class BizDataController extends GenericFlowController {
    
    @Autowired
    private ProContractService proContractService;

    @Autowired
    private BizDataService bizDataService;
    
    @Autowired
    private StaffInfoService staffInfoService;

    @Autowired
    private CodeGeneratorConfigService codeGeneratorConfigService;
    
    @Autowired
    private ExcelParseUtil<BizDataExcelVo> excelParseUtil;


    /**
     * list页面
     * @return
     */
    @RequestMapping("/list")
    public String list() {
        return "bpa/lay-bizData-list";
    }
    
    /**
     * 商务数据列表数据
     *
     * @return
     */
    @RequestMapping("/queryDataByCondition")
    @ResponseBody
    public RspVo<BizDataDomain> queryDataByCondition(BizDataVo bizDataVo, ParamPage paramPage) {
        Page<BizDataDomain> page = new Page<BizDataDomain>();
        page.setPageNum(paramPage.getPage());
        page.setPageSize(paramPage.getLimit());
        //查询时，结束日期增加一天
        if (bizDataVo.getEndDate() != null) {
            bizDataVo.setEndDate(DateUtils.addDays(bizDataVo.getEndDate(), 1));
        }
        page = bizDataService.selectPageByDomainWhere(page, bizDataVo);
        return RspVo.getSuccessResponse(page.getTotal(), page.getResult());
    }

    /**
     * 商务数据-我审批的列表数据
     *
     * @return
     */
    @RequestMapping("/queryMyCheckDataByCondition")
    @ResponseBody
    public RspVo<BizDataDomain> queryMyCheckDataByCondition(BizDataVo bizDataVo, ParamPage paramPage) {
        Page<BizDataDomain> page = new Page<BizDataDomain>();
        page.setPageNum(paramPage.getPage());
        page.setPageSize(paramPage.getLimit());
        //查询时，结束日期增加一天
        if (bizDataVo.getEndDate() != null) {
            bizDataVo.setEndDate(DateUtils.addDays(bizDataVo.getEndDate(), 1));
        }
        bizDataVo.setAddBy(SessionUserUtils.getSessionUserId());
        page = bizDataService.selectMyCheckByDomainWhere(page, bizDataVo);
        return RspVo.getSuccessResponse(page.getTotal(), page.getResult());
    }


    /**
     * 跳转到新增页面
     * @return
     */
    @RequestMapping("/add")
    public String toAdd(HttpServletRequest request) {
        AuthorizationVO authorizationVO = SessionUserUtils.getSessionAttributeForUserDtl();
        StaffInfo staffInfo = staffInfoService.selectByPrimaryKey(authorizationVO.getHrStaffId());
        request.setAttribute("staffName", staffInfo.getStaffName());
        //返回所有项目合同中的项目名称
        List<ProContract> proContractList = proContractService.selectAllContracts(null, null);
        request.setAttribute("proContractList", proContractList);
        return "bpa/lay-bizData-add";
    }
    
    /**
     * 商务数据-新增
     * @throws ParseException 
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping("/save")
    @ResponseBody
    public RspVo save(HttpServletRequest request, BizDataVo bizData, String planYear) throws ParseException {
        if(CollectionUtils.isEmpty(bizData.getBizDataDetails())){
            return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("请导入excel数据");
        }
        AuthorizationVO vo = SessionUserUtils.getSessionAttributeForUserDtl();
        String id = IdFactory.getUUIDUpper();
        bizData.setId(id);
        bizData.setHrStaffApplyId(vo.getHrStaffId());
        bizData.setHrOrgId(String.valueOf(SessionUserUtils.getSessionAttribute("bindOrgId")));
        bizData.setHrDeptId(String.valueOf(SessionUserUtils.getSessionAttribute("bindDeptId")));
        StaffInfo staffInfo = staffInfoService.selectByPrimaryKey(vo.getHrStaffId());
        bizData.setStaffName(staffInfo.getStaffName());
        bizData.setHrStaffApplyId(vo.getHrStaffId());
        bizData.setPlanYear(Integer.parseInt(planYear));
        bizData.setAddBy(vo.getId());
        bizData.setAddTime(top.infopub.mgr.util.DateUtils.getCurrentDateTime());
        String codes = codeGeneratorConfigService.generatorCode("bpa_biz_data");
        bizData.setCodes(codes);
        bizData.setProcessId(IdFactory.getUUIDUpper());
        //设置审批状态
        bizData.setProcessStatus("1");
        bizData.setUptBy(vo.getId());
        bizData.setUptTime(top.infopub.mgr.util.DateUtils.getCurrentDateTime());

        List<BizDataDetail> bizDataDetails = new ArrayList<BizDataDetail>();
        int showIdx = 0;
        for (BizDataDetail bizDataDetail : bizData.getBizDataDetails()) {
            String detailId = IdFactory.getUUIDUpper();
            bizDataDetail.setId(detailId);
            showIdx = showIdx + 1;
            bizDataDetail.setShowIdx(showIdx);
            bizDataDetail.setBizDataId(id);
            bizDataDetail.setAddBy(vo.getId());
            bizDataDetail.setAddTime(top.infopub.mgr.util.DateUtils.getCurrentDateTime());
            bizDataDetails.add(bizDataDetail);
        }
        bizDataService.save(bizData,bizDataDetails);
        LogUtil.bizLog(LogUtil.LogModelType.PROJECT, LogUtil.AcctionType.ADD,
                "商务管理 -商务事项-新增商务数据：项目名=" + bizData.getProName(), null);
        return RspVo.getSuccessResponse();
    }
    
    /**
     * 根据id查询商务数据详细  > 注意：方法命名必须为：toDealOrDetail
     *
     * @param id 投建项目id
     * @return
     * @see
     */
    @RequestMapping("/toDealOrDetail")
    public ModelAndView queryById(HttpServletRequest request, String id, String processDealWith) {
        Map<String, Object> map = new HashMap<String, Object>();
        BizDataVo bizData = bizDataService.queryById(id);
        map.put("bizData", bizData);
        // 审批flag
        request.setAttribute("processDealWith", processDealWith);
        // 审批data
        processData(request, bizData.getProcessId());
        return new ModelAndView("bpa/lay-bizData-detail", map);
    }
    
    /**
     * 导入商务数据
     * @param response 
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     * @see
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    @RequestMapping("/importExcel")
    public @ResponseBody RspVo importExcel(@RequestParam("file")MultipartFile uploadFile) throws IllegalAccessException, InvocationTargetException {
        RspVo rspVo = excelParseUtil.parser(uploadFile, BizDataExcelVo.class,1);
        if(!rspVo.isSuccess()){
            return rspVo;
        }
        List<BizDataExcelVo> excelVos = rspVo.getData();
        List<BizDataExcelVo> medalExcelVos = new ArrayList<BizDataExcelVo>();
        BigDecimal amount = BigDecimal.ZERO;
        for(BizDataExcelVo excelVo : excelVos){
            //判断导入的excel数据没有空值
            if(ObjectCheckUtil.checkObjFieldsIsNull(excelVo)){
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("数据不能为空");
            }
            //判断名称是否超过25
            if(excelVo.getItemName().trim().length() > 200){
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("名称不得超过200个字符");
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getEarlyAddup())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("前期累计数据格式不正确，数据为："+excelVo.getEarlyAddup());
            }else{
                amount = new BigDecimal(excelVo.getEarlyAddup());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setEarlyAddup(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getJanuaryValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("1月数据格式不正确，数据为："+excelVo.getJanuaryValues());
            }else{
                amount = new BigDecimal(excelVo.getJanuaryValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setJanuaryValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getFebruaryValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("2月数据格式不正确，数据为："+excelVo.getFebruaryValues());
            }else{
                amount = new BigDecimal(excelVo.getFebruaryValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setFebruaryValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getMarchValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("3月数据格式不正确，数据为："+excelVo.getMarchValues());
            }else{
                amount = new BigDecimal(excelVo.getMarchValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setMarchValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getAprilValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("4月数据格式不正确，数据为："+excelVo.getAprilValues());
            }else{
                amount = new BigDecimal(excelVo.getAprilValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setAprilValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getMayValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("5月数据格式不正确，数据为："+excelVo.getMayValues());
            }else{
                amount = new BigDecimal(excelVo.getMayValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setMayValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getJuneValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("6月数据格式不正确，数据为："+excelVo.getJuneValues());
            }else{
                amount = new BigDecimal(excelVo.getJuneValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setJuneValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getJulyValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("7月数据格式不正确，数据为："+excelVo.getJulyValues());
            }else{
                amount = new BigDecimal(excelVo.getJulyValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setJulyValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getAugustValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("8月数据格式不正确，数据为："+excelVo.getAugustValues());
            }else{
                amount = new BigDecimal(excelVo.getAugustValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setAugustValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getSeptemberValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("9月数据格式不正确，数据为："+excelVo.getSeptemberValues());
            }else{
                amount = new BigDecimal(excelVo.getSeptemberValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setSeptemberValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getOctoberValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("10月数据格式不正确，数据为："+excelVo.getOctoberValues());
            }else{
                amount = new BigDecimal(excelVo.getOctoberValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setOctoberValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getNovemberValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("11月数据格式不正确，数据为："+excelVo.getNovemberValues());
            }else{
                amount = new BigDecimal(excelVo.getNovemberValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setNovemberValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getDecemberValues())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("12月数据格式不正确，数据为："+excelVo.getDecemberValues());
            }else{
                amount = new BigDecimal(excelVo.getDecemberValues());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setDecemberValues(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getYearAddup())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("本年累计数据格式不正确，数据为："+excelVo.getYearAddup());
            }else{
                amount = new BigDecimal(excelVo.getYearAddup());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setYearAddup(amount.toString());
            }
            //判断数据格式是否为数字
            if(!isNumeric(excelVo.getTotalAddup())) {
                return ErrorCodeEnum.ERROR_COMMON_CHECK.getRspVo("开累数据格式不正确，数据为："+excelVo.getTotalAddup());
            }else{
                amount = new BigDecimal(excelVo.getTotalAddup());
                amount = amount.multiply(new BigDecimal(10000)).setScale(2, BigDecimal.ROUND_HALF_UP);
                excelVo.setTotalAddup(amount.toString());
            }
            medalExcelVos.add(excelVo);
        }
        LogUtil.bizLog(LogModelType.PROJECT, AcctionType.ADD, "excel导入商务数据 - 记录数:" + medalExcelVos.size(), null);
        return RspVo.getSuccessResponse(medalExcelVos);
    }

    /**
     * 利用正则表达式判断字符串是否是数字，正负数，且只有两位小数
     * @param str
     * @return
     */
    public static boolean isNumericTwo(String str){
        Pattern pattern = Pattern.compile("^[\\-]?[\\d]+(\\.[\\d]{0,2})?$");
        Matcher isNum = pattern.matcher(str);
        if(!isNum.matches()){
            return false;
        }
        return true;
    }
    
    /**
     * 利用正则表达式判断字符串是否是数字，正负数，且可以多位小数
     * @param str
     * @return
     */
    public static boolean isNumeric(String str){
        Pattern pattern = Pattern.compile("^[\\-]?[\\d]+.?[0-9]*$");
        Matcher isNum = pattern.matcher(str);
        if(!isNum.matches()){
            return false;
        }
        return true;
    }
    
    public static void main(String[] args) {
        System.out.println(isNumeric("22407.3637959184"));
    }
}
